package models

import (
	"encoding/json"
	"github.com/beego/beego/v2/adapter/logs"
	"github.com/beego/beego/v2/client/orm"
	"go-cmdb/pkg"
	"strconv"
	"strings"
	"time"
)

//User 后台用户
type User struct {
	BModel
	Memo     string `orm:"column(memo)" json:"memo" form:"memo"`                //备注
	UserName string `orm:"column(user_name)" json:"user_name" form:"user_name"` // 用户名
	RealName string `orm:"column(real_name)" json:"real_name" form:"real_name"` // 真实姓名
	Password string `orm:"column(password)" json:"password" form:"password"`    // 密码(md5(明文)加密)
	Email    string `orm:"column(email)" json:"email" form:"email"`             // 邮箱
	Phone    string `orm:"column(phone)" json:"phone" form:"phone"`             // 手机号
	Status   uint8  `orm:"column(status)" json:"status" form:"status"`          // 状态(0:删除1:正常 2:暂停使用)
	RoleIds  string `orm:"column(role_ids)" json:"role_ids" form:"role_ids"`    // 角色ids
}

//MarshalJSON 格式化时间
func (tb User) MarshalJSON() ([]byte, error) {

	type Alias User

	return json.Marshal(struct {
		Alias
		CreatedAt string `json:"created_at"`
		UpdatedAt string `json:"updated_at"`
	}{
		Alias:     (Alias)(tb),
		CreatedAt: tb.CreatedAt.Format("2006-01-02 15:04:05"),
		UpdatedAt: tb.UpdatedAt.Format("2006-01-02 15:04:05"),
	})
}
func (tb *User) GetRoleIds() (lst []uint64) {

	for _, v := range strings.Split(tb.RoleIds, ",") {
		id, _ := strconv.ParseUint(v, 10, 64)
		if id <= 0 {
			continue
		}
		lst = append(lst, id)
	}
	return

}

func NewUser() *User {
	return &User{}
}

//TableName 表名
func (*User) TableName() string {
	return UserTable
}

//// Delete 删除主用户及权限
//func (tb *User) Delete(adminsids []uint64) error {
//
//	db := orm.NewOrm()
//	return db.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
//
//		delAdmin := txOrm.QueryTable(new(User)).Filter("id__in", adminsids)
//		if _, err := delAdmin.Delete(); err != nil {
//			return err
//		}
//
//		return nil
//
//	})
//
//}

func (tb *User) FinUser(userName, password string) (m *User, err error) {

	db := orm.NewOrm()
	m = &User{}
	if err = db.QueryTable(new(User)).Filter("user_name", userName).Filter("password", password).One(m); err != nil {
		logs.Error("[sql]", err)
	}

	if m.ID <= 0 {
		m = nil
		return
	}
	return

}

func (tb *User) GetByPage(pageSize, pageIndex uint64) (lst []User, count uint64, err error) {

	db := orm.NewOrm()
	offset := (pageIndex - 1) * pageSize
	q := db.QueryTable(NewUser()).OrderBy("-updated_at")
	var c int64
	c, err = q.Count()
	count = uint64(c)
	q.Offset(offset).Limit(pageSize).All(&lst)
	return

}

func (tb *User) Find(id uint64) (m *User, err error) {
	db := orm.NewOrm()
	m = &User{}
	err = db.QueryTable(NewUser()).Filter("id", id).One(m)
	if m.ID <= 0 {
		m = nil
	}
	return
}

type AddUserReq struct {
	Name     string `json:"name"`
	RealName string `json:"real_name"`
	Phone    string `json:"phone"`
	Email    string `json:"email"`
	RoleIds  string `orm:"column(role_ids)" json:"role_ids" form:"role_ids"` // 角色ids

}

func (tb *User) Add(uid uint64, req AddUserReq) (err error) {
	db := orm.NewOrm()
	now := time.Now()
	tb.Status = 1
	tb.UpdatedBy = uid
	tb.UpdatedAt = now
	tb.CreatedAt = now
	tb.CreatedBy = uid
	tb.Phone = req.Phone
	tb.Email = req.Email
	tb.RoleIds = req.RoleIds
	tb.RealName = req.RealName
	tb.UserName = req.Name
	tb.Password = pkg.FormatPwd(pkg.DefaultPwd)
	_, err = db.Insert(tb)

	return
}

type UpdateUserReq struct {
	ID       uint64 `json:"id"`
	Name     string `json:"name"`
	RealName string `json:"real_name"`
	Phone    string `json:"phone"`
	Email    string `json:"email"`
	RoleIds  string `orm:"column(role_ids)" json:"role_ids" form:"role_ids"` // 角色ids

}

//type StatusUserReq struct {
//	ID     uint64 `json:"id" form:"id"`
//	Status uint8  `json:"status" form:"status"`
//}

type RemoveUserReq struct {
	ID uint64 `json:"id" form:"id"`
}
type EnableUserReq struct {
	ID     uint64 `json:"id" form:"id"`
	Status uint8  `json:"status" form:"status"`
}

func (tb *User) CStatus(status uint8, id, uid uint64) (err error) {

	now := time.Now()
	tb.ID = id
	tb.UpdatedAt = now
	tb.UpdatedBy = uid
	tb.Status = status
	db := orm.NewOrm()
	_, err = db.Update(tb, "status", "updated_at", "updated_by")

	return
}
func (tb *User) Update(uid uint64, req UpdateUserReq) (err error) {
	db := orm.NewOrm()
	now := time.Now()
	tb.UpdatedBy = uid
	tb.UpdatedAt = now
	tb.Phone = req.Phone
	tb.Email = req.Email
	tb.RoleIds = req.RoleIds
	tb.RealName = req.RealName
	tb.UserName = req.Name
	tb.ID = req.ID
	_, err = db.Update(tb, "phone", "email", "updated_at", "updated_by", "role_ids", "real_name", "user_name")
	return
}
func (tb *User) CountByName(name string) (count uint64, err error) {
	db := orm.NewOrm()
	c, e := db.QueryTable(NewUser()).Filter("user_name", name).Count()
	err = e
	count = uint64(c)
	return
}

type ChangePwdReq struct {
	Pwd01  string `json:"pwd_01"`
	Pwd02  string `json:"pwd_02"`
	OldPwd string `json:"old_pwd"`
}

type RestPwdReq struct {
	ID uint64 `json:"id"`
}

func (tb *User) ChangePwd(uid uint64, pwd string) (err error) {
	db := orm.NewOrm()
	now := time.Now()
	tb.UpdatedBy = uid
	tb.UpdatedAt = now
	tb.ID = uid
	tb.Password = pwd
	_, err = db.Update(tb, "password", "updated_at", "updated_by")
	return
}

type ChangeUserInfoReq struct {
	Name     string `json:"name"`
	RealName string `json:"real_name"`
	Phone    string `json:"phone"`
	Email    string `json:"email"`
}

//ChangeUserInfo 更改自己的用户信息
func (tb *User) ChangeUserInfo(uid uint64, req ChangeUserInfoReq) (err error) {
	db := orm.NewOrm()
	now := time.Now()
	tb.UpdatedBy = uid
	tb.UpdatedAt = now
	tb.Phone = req.Phone
	tb.Email = req.Email
	tb.RealName = req.RealName
	tb.UserName = req.Name
	tb.ID = uid
	_, err = db.Update(tb, "phone", "email", "updated_at", "updated_by", "real_name")
	return
}
